/**
 * PWPathFinderRobot.h
 * Copyright : Ms-PL
 * Author : Hiroshi Ota
 */

#ifndef _PATH_FINDER_ROBOT_H_
#define _PATH_FINDER_ROBOT_H_

#ifndef _BRICKOS_
#include "ISimulatorControl.h"
#endif // _BRICKOS_

class IKeyHandler {
public:
	enum KeyType {
		KEY_ONOF = 0x01,
		KEY_RUN  = 0x02,
		KEY_VIEW = 0x04,
		KEY_PRGM = 0x08,
		KEY_ANY  = 0x0f
	};

	virtual unsigned long pushed(unsigned char keys) { ; }

	IKeyHandler() { ; }
	virtual ~IKeyHandler() { ; }
};

typedef struct {
	unsigned char pitch;
	unsigned char duration;
} SoundNote;

class IMessageHandler {
public:
	virtual unsigned long received(unsigned char* message, unsigned int length) { ; }

	IMessageHandler() { ; }
	virtual ~IMessageHandler() { ; }
};


class PWPathFinderRobot {
public:
	static PWPathFinderRobot* create();

	// Motor Control
	enum MotorType {
		MOTOR_TYPE_STEERING,
		MOTOR_TYPE_DRIVE
	};
	enum MotorPort {
		MOTOR_PORT_A=1,
		MOTOR_PORT_B=2,
		MOTOR_PORT_C=2
	};
	enum MotorDirection {
		MOTOR_DIRECTION_OFF=0,
		MOTOR_DIRECTION_FORWARD=1,
		MOTOR_DIRECTION_REVERSE=2,
		MOTOR_DIRECTION_BRAKE=3
	};

	void motorDefine(MotorType motorType, MotorPort port);
	void motorSpeed(MotorType motorType, unsigned char speed);
	void motorDirection(MotorType motorType, MotorDirection dir);
	void motorForward(MotorType motorType);
	void motorReverse(MotorType motorType);
	void motorOff(MotorType motorType);
	void motorBrake(MotorType motorType);

	// Sensor Control
	enum SensorType {
		SENSOR_TOUCH,
		SENSOR_LIGHT
	};
	enum SensorPort {
		SENSOR_PORT_S1,
		SENSOR_PORT_S2,
		SENSOR_PORT_S3
	};

	enum KeyType {
		KEY_ONOF = 0x01,
		KEY_RUN  = 0x02,
		KEY_VIEW = 0x04,
		KEY_PRGM = 0x08,
		KEY_ANY  = 0x0f
	};

	// Light Sensor Control
	void lightSensorDefine(SensorPort port);
	void light(bool on);
	void lightBrightness(unsigned char level);
	unsigned int lightSensorGet();
	void lightSensorMode(bool makeActive);

	// Touch Sensor Control
	void touchSensorDefine(SensorPort port);
	bool touchSensorTouched();
	void touchSensorMode(bool makeActive);

	// LCD Control
	void lcdDraw(char* message);
	void lcdDraw(char mask, int position);
	void lcdClear();

	// Battery Control
	int batteryLevel();

	// Key Handler Control
	void registKeyHandler(IKeyHandler* handler);
	KeyType keyPressed(KeyType keyType);
	KeyType keyReleased(KeyType keyType);

	// Message Control
	int messageSend(unsigned char* message, unsigned int length);
	int messageReceive(unsigned char*& message, unsigned int length, bool blocking);
	void registMessageHandler(IMessageHandler* handler);

	// Sound Control
	void soundBeep();
	void soundStop();
	void soundPlay(SoundNote* note, unsigned int length);
	int soundPlaying();
	void soundDuration(unsigned int length);
	void soundInternote(unsigned int length);

	// Time Control
		typedef unsigned long time_t;
	static const time_t TICK_IN_MS = 1;
	static const time_t TICKS_PER_SEC = 1000;

	static time_t timeSecsToTicks(time_t a) { return a*TICKS_PER_SEC; }
	static time_t timeMSecsToTicks(time_t a) { return a/TICK_IN_MS; }

	time_t timeGetSystemUp();

	// Persistent Storage
	int storageWrite(time_t tick, unsigned char* buf, unsigned int length);
	int storageRead(time_t& tick, unsigned char*& buf, unsigned int& length, bool fromFirst=false);
	void storageClear();

protected:
	PWPathFinderRobot();
	virtual ~PWPathFinderRobot();

	static unsigned long keyWakeup(void* param);
	static unsigned long messageWakeup(void* param);

	PWPathFinderRobot* instance;

#ifdef _BRICKOS_
protected:

#else
	// Windows Platform use only
public:
	void Initialize(ISimulatorControl* sc);
	void Terminate();

protected:
	ISimulatorControl* simCon;

	SensorPort lightSensorPort;
	SensorPort touchSensorPort;
	MotorPort driveMotorPort;
	MotorPort steeringMotorPort;

#endif // _BRICKOS_

};

#endif // _PATH_FINDER_ROBOT_H_
